<template>
    <div>
        <Modal :title="title" :value="value" @input="changeValue">
            <Form :label-width="46">
                <FormItem label="①">
                    <h6>选择模板类型，准备单据信息</h6>
                    <p>选择您要导入数据的模板名称，如果您没有自定义模板，请使用系统标准模板。一次最多导入1000条。</p>
                    <Select style="width:200px;margin-right: 15px;" v-model="templateId" @on-change="handleTemplateChange">
                        <Option
                            v-for="(item, index) in templateList"
                            :key="index"
                            :value="item.value"
                            :label="item.label"
                        ></Option>
                    </Select>
                    <Button class="download-btn" icon="ios-download-outline" type="primary" @click="downloadTemplate">点击下载模板</Button>
                </FormItem>
                <FormItem label="②">
                    <h6>上传数据文件</h6>
                    <p>目前支持的文件类型为 {{acceptTips}} 文件{{size}}M。</p>
                    <Upload
                        :before-upload="beforeUpload"
                        :accept="accept"
                        :format="format"
                        :action="action"
                    >
                        <Button type="primary">添加文件</Button>
                    </Upload>
                    <div>{{fileName}}</div>
                    <Progress
                        v-show="process.visible"
                        :percent="process.percent"
                        :status="process.status"
                    ></Progress>
                </FormItem>
            </Form>
            <div slot="footer">
                <Button type="default" @click="changeValue(false)">取消</Button>
                <Button type="primary" @click="importExcel" :loading="loading" :disabled="!templateId">导入</Button>
            </div>
        </Modal>
        <!-- 导入成功 -->
        <Modal width="390" title="导入成功" v-model="successModal">
            <div class="success-content">
                <Icon color="#36C7A1" :size="36" type="ios-checkmark-circle" />
                <span class="succes-text">导入完成</span>
            </div>
            <div slot="footer">
                <Button type="default" @click="closeAll">查看导入的数据</Button>
                <Button type="primary" @click="renewImport">继续导入</Button>
            </div>
        </Modal>
        <!-- 导入失败 -->
        <Modal width="746" v-model="failModal.visible" :title="importFlag ? '部分数据导入成功' : failModal.title">
            <Table :height="350" :data="failData" :columns="failColumns"></Table>
            <div slot="footer">
                <template v-if="importFlag">
                    <Button type="default" @click="closeAll">查看导入的数据</Button>
                    <Button type="primary" @click="renewImport">继续导入</Button>
                </template>
                <template v-else>
                    <Button type="default" @click="failModal.visible = false">取消</Button>
                    <Button type="primary" @click="renewImport">重新导入</Button>
                </template>
            </div>
        </Modal>
    </div>
</template>
<script>
import axios from '@/libs/api.request'
import { importXlsByTemplateUrl } from '@/api/invt'

export default {
    props: {
        // 弹窗title
        title: {
            type: String,
            default: '导入模板'
        },
        // 弹窗状态 可用v-model
        value: {
            type: Boolean,
            default: false
        },
        // 模板列表
        templateList: {
            type: Array,
            default: _ => []
        },
        // 默认模板上传地址
        defautlAction: {
            type: String
        },
        // 自定义上传地址
        action: {
            type: String,
            default: importXlsByTemplateUrl
        },
        // 文件格式
        format: {
            type: Array,
            default: _ => ['xls', 'xlsx', 'csv']
        },
        // 文件大小  单位：M
        size: {
            type: Number,
            default: 4
        },
        // 刷新方法 有导入成功的数据 弹窗关闭时调用
        refreshMethod: {
            type: Function,
            default: _ => {}
        },
        // 导入的额外参数
        importParams: {
            type: Object,
            default: () => {
                return {}
            }
        }
    },
    data () {
        return {
            // 已选择模板id
            templateId: '',
            // 已选择文件名
            fileName: '',
            // 进度条信息
            process: {
                percent: 0,
                status: 'success',
                visible: false
            },
            // 失败弹窗信息
            failModal: {
                title: '导入失败',
                visible: false
            },
            // 成功弹窗信息
            successModal: false,
            // 失败table
            failData: [],
            failColumns: [
                {
                    title: '行号',
                    key: 'rowNum',
                    align: 'center',
                    width: 100
                },
                {
                    title: '错误描述',
                    align: 'center',
                    key: 'message',
                    tooltip: true
                }
            ],
            importFlag: false, // 导入结果
            // 导入loading
            loading: false
        }
    },
    computed: {
        accept () {
            return this.format.map(item => `.${item}`).join(',')
        },
        acceptTips () {
            return this.format.map(item => `*.${item}`).join('，')
        }
    },
    watch: {
        value (n) {
            this.handleVisibleChange(n)
        }
    },
    methods: {
        // 处理选择模板改变 获取模板url
        handleTemplateChange (value) {
            const target = this.templateList.find(item => item.value === value)
            if (target) {
                this.templateUrl = target.url
            }
        },
        // 下载模板
        downloadTemplate () {
            if (this.templateUrl) {
                window.open(this.templateUrl)
            } else {
                this.$Message.warning(this.templateId ? '没有可下载的模板' : '请选择模板')
            }
        },
        // 导入前拦截
        beforeUpload (file) {
            if (this.checkFileFormat(file) && this.checkFileSize(file)) {
                this.file = file
                this.fileName = file.name
            } else {
                this.file = ''
                this.fileName = ''
            }
            this.setProcess({ visible: false })
            return false
        },
        // 检查文件格式
        checkFileFormat (file) {
            const fileNameList = file.name.split('.')
            const fileFormat = fileNameList[fileNameList.length - 1].toLocaleLowerCase()
            if (this.format.indexOf(fileFormat) < 0) {
                this.$Message.warning(`只支持${this.acceptTips}格式文件`)
                return false
            }
            return true
        },
        // 检查文件大小
        checkFileSize (file) {
            const maxSize = this.size * 1024 * 1024
            if (file.size > maxSize) {
                this.$Message.warning(`文件${file.name}不能超过${this.size}M`)
                return false
            }
            return true
        },
        // 设置进度条
        setProcess ({ percent = 0, visible = true, status = 'success' }) {
            this.process.percent = percent
            this.process.visible = visible
            this.process.status = status
        },
        // 导入文件
        importExcel () {
            if (!this.file) {
                this.$Message.warning(this.process.status === 'success' ? '请选择文件' : '请重新选择文件')
                return
            }
            this.loading = true
            // 开启进度条
            this.setProcess({ visible: true })
            // 如果是自定义模板 带上自定义模板id 和 businessType
            let params = {}; let url = this.defautlAction
            // 默认模板id -1  不是默认模板则用自定义模板的上传地址
            if (this.templateId != -1) {
                url = this.action
                params.excelTemplateId = this.templateId
            }
            Object.keys(this.importParams).forEach(key => {
                params[key] = this.importParams[key]
            })
            // 设置文件数据
            const data = new FormData()
            data.append('file', this.file)
            axios
                .request({
                    url,
                    params,
                    data,
                    method: 'post',
                    onUploadProgress: progressEvent => {
                        if (progressEvent.lengthComputable) {
                            let num = Math.round(
                                (progressEvent.loaded / progressEvent.total) *
                                    100
                            )
                            this.setProcess({ percent: num })
                        }
                    }
                })
                .then(res => {
                    // 清空文件 避免重复上传
                    this.file = ''
                    this.tempId = res.data.id || ''
                    if (res.data.code === '0000') {
                        this.importFlag = true // 已产生主键
                        if (!res.data.data || res.data.data.length <= 0) {
                            this.successModal = true
                        }
                    } else {
                        // 导入失败  进度条红色
                        this.setProcess({ percent: 100, status: 'wrong' })
                    }
                    // 判断是否有错误信息
                    if (
                        res.data.data &&
                        res.data.data.length > 0
                    ) {
                        this.failData = res.data.data
                        this.failModal.visible = true
                    } else if (res.data.code !== '0000') {
                        this.$Message.warning(
                            res.data.msg || '导入失败'
                        )
                    }
                    this.loading = false
                })
                .catch(err => {
                    this.loading = false
                    this.setProcess({ percent: 100, status: 'wrong' })
                })
        },
        // 重新导入
        renewImport () {
            // 关闭所有弹窗
            this.successModal = false
            this.failModal.visible = false
            // 清空文件和进度条
            this.clearImportData()
        },
        // 更改value
        changeValue (v) {
            this.$emit('input', v)
        },
        // 清空导入数据  清空文件并隐藏进度条
        clearImportData () {
            this.fileName = ''
            this.file = ''
            this.setProcess({ visible: false })
        },
        // 关闭所有弹窗
        closeAll () {
            this.successModal = false
            this.failModal.visible = false
            this.changeValue(false)
        },
        // 处理弹窗显示隐藏状态改变
        handleVisibleChange (v) {
            if (v) {
                let { templateId, templateUrl } = this
                // 如果 选择的旧模板值 则判断模板值是否有效(fix:templateList数据变化后已选择的失效数据没有清空的bug)
                if (templateId !== '') {
                    const index = this.templateList.findIndex(item => item.value === this.templateId)
                    if (index < 0) {
                        templateId = ''
                        templateUrl = ''
                    }
                }
                // 设置默认选中一个模板
                if (templateId === '' && this.templateList.length) {
                    let index = 0
                    if (this.templateList.length > 1 && this.templateList[0].value < 0) {
                        index = 1
                    }
                    templateId = this.templateList[index].value
                    templateUrl = this.templateList[index].url // 已选择的模板id
                }
                this.$nextTick(() => {
                    this.templateId = templateId
                    this.templateUrl = templateUrl
                })
            } else {
                this.importFlag && this.refreshMethod(this.tempId)
                this.importFlag = false
                this.clearImportData()
            }
        }
    }
}
</script>
<style lang="less" scoped>
.success-content {
    line-height: 40px;
    font-size: 14px;
    .succes-text {
        margin-left: 15px;
    }
}
</style>
